package com.matrix.framework.sysconfig.iplist.controller;

import com.matrix.framework.core.annotation.validation.LogCollector;
import com.matrix.framework.core.annotation.validation.Valid;
import com.matrix.framework.core.common.result.Result;
import com.matrix.framework.sysconfig.iplist.data.IpSecurityRuleDto;
import com.matrix.framework.sysconfig.iplist.data.IpSecurityRulePo;
import com.matrix.framework.sysconfig.iplist.service.IpSecurityService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * IP安全管理控制器
 *
 * Copyright © 海平面工作室 版权所有
 *
 * @Author: Leo
 * @Create: 2024/12/1 15:30
 * @Since 1.2
 */
@RestController
@RequestMapping("/security/ip")
public class IpSecurityController {

    private final IpSecurityService ipSecurityService;

    public IpSecurityController(IpSecurityService ipSecurityService) {
        this.ipSecurityService = ipSecurityService;
    }

    /**
     * 分页获取IP安全规则列表（支持条件过滤）
     * @param dto 查询条件及分页参数
     * @return 分页IP安全规则对象
     */
    @PostMapping("/list")
    public Mono<Result<IpSecurityRuleDto>> list(@RequestBody IpSecurityRuleDto dto) {
        return ipSecurityService.findRules(dto)
                .map(result -> Result.ok(result))
                .onErrorResume(e -> Mono.just(Result.<IpSecurityRuleDto>fail().message(e.getMessage())));
    }

    /**
     * 保存IP安全规则
     */
    @LogCollector
    @PostMapping("/save")
    public Mono<ResponseEntity<Result<IpSecurityRulePo>>> save(@Valid @RequestBody IpSecurityRulePo rule, ServerWebExchange exchange) {
        return ipSecurityService.saveRule(rule)
                .map(savedRule -> ResponseEntity.ok(Result.ok(savedRule)))
                .onErrorResume(e -> Mono.just(ResponseEntity.ok(Result.<IpSecurityRulePo>fail().message(e.getMessage()))));
    }

    /**
     * 删除IP安全规则
     */
    @LogCollector
    @DeleteMapping("/delete/{id}")
    public Mono<ResponseEntity<Result<Void>>> delete(@PathVariable Long id, ServerWebExchange exchange) {
        return ipSecurityService.deleteRule(id)
                .then(Mono.just(ResponseEntity.ok(Result.<Void>ok(null))))
                .onErrorResume(e -> Mono.just(ResponseEntity.ok(Result.<Void>fail().message(e.getMessage()))));
    }

    /**
     * 获取IP访问统计
     */
    @GetMapping("/statistics/{ipAddress}")
    public Mono<ResponseEntity<Result<Map<String, Object>>>> getIpStatistics(
            @PathVariable String ipAddress,
            @RequestParam(defaultValue = "7") int days,
            ServerWebExchange exchange) {
        return ipSecurityService.getIpStatistics(ipAddress, days)
                .map(stats -> ResponseEntity.ok(Result.ok(stats)))
                .onErrorResume(e -> Mono.just(ResponseEntity.ok(Result.<Map<String, Object>>fail().message(e.getMessage()))));
    }

    /**
     * 清理过期记录
     */
    @LogCollector
    @PostMapping("/cleanup")
    public Mono<ResponseEntity<Result<Map<String, Object>>>> cleanupRecords(
            @RequestParam(defaultValue = "30") int days,
            ServerWebExchange exchange) {
        return ipSecurityService.cleanExpiredRecords(days)
                .map(count -> {
                    Map<String, Object> result = Map.of(
                            "deletedCount", count,
                            "message", "成功清理 " + count + " 条过期记录"
                    );
                    return ResponseEntity.ok(Result.ok(result));
                })
                .onErrorResume(e -> Mono.just(ResponseEntity.ok(Result.<Map<String, Object>>fail().message(e.getMessage()))));
    }

    /**
     * 验证IP访问权限（测试接口）
     */
    @PostMapping("/validate")
    public Mono<ResponseEntity<Result<Map<String, Object>>>> validateIpAccess(
            @RequestParam String ipAddress,
            @RequestParam(required = false) String username,
            @RequestParam String apiPath,
            ServerWebExchange exchange) {
        return ipSecurityService.validateIpAccess(ipAddress, username, apiPath)
                .map(result -> {
                    Map<String, Object> data = Map.of(
                            "allowed", result.isAllowed(),
                            "reason", result.getReason(),
                            "action", result.getAction(),
                            "ipAddress", ipAddress,
                            "username", username,
                            "apiPath", apiPath
                    );
                    return ResponseEntity.ok(Result.ok(data));
                })
                .onErrorResume(e -> Mono.just(ResponseEntity.ok(Result.<Map<String, Object>>fail().message(e.getMessage()))));
    }

    /**
     * 检查IP访问频率（测试接口）
     */
    @PostMapping("/rate-limit")
    public Mono<ResponseEntity<Result<Map<String, Object>>>> checkRateLimit(
            @RequestParam String ipAddress,
            @RequestParam(required = false) String username,
            @RequestParam String apiPath,
            ServerWebExchange exchange) {
        return ipSecurityService.checkRateLimit(ipAddress, username, apiPath)
                .map(result -> {
                    Map<String, Object> data = Map.of(
                            "allowed", result.isAllowed(),
                            "reason", result.getReason(),
                            "remainingRequests", result.getRemainingRequests(),
                            "resetTime", result.getResetTime(),
                            "ipAddress", ipAddress,
                            "username", username,
                            "apiPath", apiPath
                    );
                    return ResponseEntity.ok(Result.ok(data));
                })
                .onErrorResume(e -> Mono.just(ResponseEntity.ok(Result.<Map<String, Object>>fail().message(e.getMessage()))));
    }

    /**
     * 获取IP安全状态概览
     */
    @GetMapping("/overview")
    public Mono<ResponseEntity<Result<Map<String, Object>>>> getOverview(ServerWebExchange exchange) {
        // 这里可以添加更多统计信息
        Map<String, Object> overview = Map.of(
                "totalRules", 0, // 可以从数据库统计
                "activeRules", 0,
                "blockedIps", 0,
                "whitelistedIps", 0,
                "lastCleanup", System.currentTimeMillis()
        );
        return Mono.just(ResponseEntity.ok(Result.ok(overview)));
    }
} 